package com.smartrobot.robot;

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;

import com.smartrobot.util.ConvUtil;



public class GtalkRobot extends AbstractRobot{

	private GtalkRobotListener listener;
	
	private XMPPConnection connection;
	
	private static Logger log=Logger.getLogger(GtalkRobot.class);
	@Override
	public boolean login() {
		log.info("GtalkRobot trying to login....");
     boolean success=false;
        
        connection=getConnection();
        if(connection==null || !connection.isConnected()){
            return false;
        }
      
        ChatManager manager=connection.getChatManager();
        
        
        manager.addChatListener(new ChatManagerListener() {
			
			@Override
			public void chatCreated(Chat chat, boolean arg1) {
				chat.addMessageListener(listener);
				
			}
		});
       
        success=true;
       
       return success;
	}
	
	
	private XMPPConnection getConnection(){
        if(connection!=null && connection.isConnected()){
            return connection;
        }

        int times=0;
        while(times<3 && (connection==null ||!connection.isConnected())){
            try {
                
                internalGetConnection();
            } catch (XMPPException ex) {
                if(times<3){
                    System.err.println("Encountered errors when connecting to server, will try again!"+times);
                    log.error("Encountered errors when connecting to server, will try again!"+times);
                }else{
                	log.error("Encountered errors when connecting to server:"+ex.toString());
                }
            }

            times++;
        }
        
        return connection;
    }

    private void internalGetConnection() throws XMPPException{
      
        XMPPConnection.DEBUG_ENABLED = false;
        //connection = new XMPPConnection(ConvUtil.getProperty("GtalkDomain"));
        ConnectionConfiguration config=new ConnectionConfiguration(ConvUtil.getProperty("GtalkIP"),Integer.parseInt(ConvUtil.getProperty("GtalkPort")),ConvUtil.getProperty("GtalkDomain"));
//        config.setCompressionEnabled(true);
//        config.setSASLAuthenticationEnabled(false);
        connection = new XMPPConnection(config);
        connection.connect();
        connection.login(ConvUtil.getProperty("GtalkRobotID"), ConvUtil.getProperty("GtalkPassword"));

}

	@Override
	public synchronized boolean addFriend(String email, String name) {
		boolean isSuccess=false;
        Roster roster=connection.getRoster();
        try {
			roster.createEntry(email, name, null);
			isSuccess=true;
		} catch (XMPPException e) {
			isSuccess=false;
			e.printStackTrace();
		}
		
		return isSuccess;
	}

	@Override
	public boolean localContainFriend(String emailAddress) {
		Roster roster=connection.getRoster();
		return roster.contains(emailAddress);
	}

	@Override
	public Map<String, String> localGetFriendList() {
		Roster roster=connection.getRoster();
		Map<String,String> fList=new HashMap<String,String>();
		for(RosterEntry entry:roster.getEntries()){
			fList.put(entry.getUser(), entry.getName());
		}
		return fList;
	}

	@Override
	public String localGetOnlineStatus(String emailAddress) {
		String status="";
		Presence pres=connection.getRoster().getPresence(emailAddress);
		if(pres.isAvailable() || pres.isAway()){
			status="ONLINE";
		}else{
			//status="OFFLINE";
			status="ONLINE";
		}
		return status;
	}

	@Override
	public String localGetDisplayName(String emailAddress) {
		return connection.getRoster().getEntry(emailAddress).getName();
	}


	public void setListener(GtalkRobotListener listener) {
		this.listener = listener;
	}

	@Override
	public boolean checkLogin() {
		if(this.connection!=null && this.connection.isConnected()){
			return true;
		}else{
			return this.login();
		}

	}

	@Override
	public String getName() {
		return "GtalkRobot";
	}
	
}
